<!doctype html>
<html>
<head>
    <meta charset="utf-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1">
    <meta name="viewport" content="width=device-width, initial-scale=1">
    <title>xeokit Example</title>
    <link href="../css/pageStyle.css" rel="stylesheet"/>
    <script src="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/5.13.0/js/all.min.js"></script>

    <style>

        #myNavCubeCanvas {
            position: absolute;
            width: 250px;
            height: 250px;
            bottom: 50px;
            right: 10px;
            z-index: 200000;
        }

        .xeokit-camera-pivot-marker {
            color: #ffffff;
            position: absolute;
            width: 25px;
            height: 25px;
            border-radius: 15px;
            border: 2px solid #ebebeb;
            background: black;
            visibility: hidden;
            box-shadow: 5px 5px 15px 1px #000000;
            z-index: 10000;
            pointer-events: none;
        }

    </style>

</head>

<body>
<input type="checkbox" id="info-button"/>
<label for="info-button" class="info-button"><i class="far fa-3x fa-question-circle"></i></label>
<canvas id="myCanvas"></canvas>
<canvas id="myNavCubeCanvas"></canvas>
<div class="slideout-sidebar">
    <h1>Lyon city model loading into SceneModels with data textures</h1>
    <p>XKT model with double-precision geometry, rendered <b>with</b> data texture scene representation enabled</p><br>
    <h3>Stats</h3>
    <ul>
        <li>
            <div id="time">Loading JavaScript modules...</div>
        </li>
    </ul>
    <h3>Components used</h3>
    <ul>
        <li>
            <a href="../../docs/class/src/viewer/Viewer.js~Viewer.html"
               target="_other">Viewer</a>
        </li>
        <li>
            <a href="../../docs/class/src/plugins/XKTLoaderPlugin/XKTLoaderPlugin.js~XKTLoaderPlugin.html"
               target="_other">XKTLoaderPlugin</a>
        </li>
    </ul>
    <h3>Resources</h3>
    <ul>
        <li>
            <a href="https://www.notion.so/xeokit/Compact-Model-Representation-using-Data-Textures-e8093ae372fa47bf9995c26dc24ccd53?pvs=4"
               target="_other">Compact Model Representation using Data Textures</a>
        </li>
        <li>Model provided by <a href="https://bimdata.io" target="_other">BIMData.io</a></li>
    </ul>

</div>
</body>

<script type="module">

    //------------------------------------------------------------------------------------------------------------------
    // Import the modules we need for this example
    //------------------------------------------------------------------------------------------------------------------

    import {
        Viewer,
        XKTLoaderPlugin,
        DirLight,
        AmbientLight,
        NavCubePlugin,
        PhongMaterial,
        Mesh,
        ReadableGeometry,
        buildPlaneGeometry,
        FastNavPlugin
    } from "../../dist/xeokit-sdk.min.es.js";

    //------------------------------------------------------------------------------------------------------------------
    // Create a Viewer with a logarithmic depth buffer
    //------------------------------------------------------------------------------------------------------------------

    const viewer = new Viewer({
        canvasId: "myCanvas",
        transparent: true
    });

    viewer.cameraControl.enablePivotSphere({
        size: 1
    });

    // Enable data texture model representation for
    // all subsequently created SceneModels (unless they override it to be disabled)

    viewer.scene.dtxEnabled = true; // Default is false

    //------------------------------------------------------------------------------------------------------------------
    // Higher-quality SAO configuration
    //------------------------------------------------------------------------------------------------------------------

    viewer.scene.sao.bias = -.3;
    viewer.scene.sao.numSamples = 50;
    viewer.scene.sao.kernelRadius = 200;

    //------------------------------------------------------------------------------------------------------------------
    // Higher-quality rendering when camera still, lower-quality when moving
    //------------------------------------------------------------------------------------------------------------------

    //new FastNavPlugin(viewer);

    //------------------------------------------------------------------------------------------------------------------
    // Configure Camera
    //
    // Since our viewer has a logarithmic depth buffer,
    // we can set a huge distance for the Camera's far clipping plane
    //------------------------------------------------------------------------------------------------------------------

    viewer.camera.eye = [1841341.4943041557, 2435.7015793568917, -5182009.256037191];
    viewer.camera.look = [1842215.561857325, -98.53293939639616, -5177009.767748618];
    viewer.camera.up = [0.07693555158566205, 0.8946686100264034, 0.4400556773132614];

    viewer.camera.perspective.near = 1.0;
    viewer.camera.perspective.far = 10000000; // 10000km

    viewer.camera.ortho.near = 1.0;
    viewer.camera.ortho.far = 10000000; // 10000km

    //------------------------------------------------------------------------------------------------------------------
    // Configure CameraControl
    //
    // Show a dot about the pivot point, whenever we orbit the Camera
    //------------------------------------------------------------------------------------------------------------------

    viewer.cameraControl.followPointer = true;
    viewer.cameraControl.smartPivot = true;

    const pivotElement = document.createRange().createContextualFragment("<div class='xeokit-camera-pivot-marker'></div>").firstChild;
    document.body.appendChild(pivotElement);
    viewer.cameraControl.pivotElement = pivotElement;

    //------------------------------------------------------------------------------------------------------------------
    // Tweak edges color
    //------------------------------------------------------------------------------------------------------------------

    viewer.scene.edgeMaterial.edgeColor = [.3, .3, .3];

    //------------------------------------------------------------------------------------------------------------------
    // Replace the Scene's default lights
    //------------------------------------------------------------------------------------------------------------------

    viewer.scene.clearLights();

    new AmbientLight(viewer.scene, {
        color: [1, 1, 1],
        intensity: 0.2
    });

    new DirLight(viewer.scene, {
        dir: [0.8, -0.8, 0.8],
        color: [1.0, 1.0, 1.0],
        intensity: 1.0,
        space: "world"
    });

    new DirLight(viewer.scene, {
        dir: [0.0, -0.8, -0.8],
        color: [0.8, 0.8, 1.0],
        intensity: 0.4,
        space: "world"
    });

    new FastNavPlugin(viewer, {
        hideEdges: true,
        hideSAO: true,
        hideColorTexture: false,
        hidePBR: false,
        hideTransparentObjects: false,
        scaleCanvasResolution: false,
        scaleCanvasResolutionFactor: 0.5,
        delayBeforeRestore: true,
        delayBeforeRestoreSeconds: 0.4
    });

    //----------------------------------------------------------------------------------------------------------------------
    // Add a NavCube
    //----------------------------------------------------------------------------------------------------------------------

    new NavCubePlugin(viewer, {
        canvasId: "myNavCubeCanvas",
        visible: true,           // Initially visible (default)
        size: 250,               // NavCube size in pixels (default is 200)
        alignment: "topRight",   // Align NavCube to top-left of Viewer canvas
        topMargin: 170,          // 170 pixels margin from top of Viewer canvas
        cameraFly: true,       // Fly camera to each selected axis/diagonal
        cameraFitFOV: 45,        // How much field-of-view the scene takes once camera has fitted it to view
        cameraFlyDuration: 0.5 // How long (in seconds) camera takes to fly to each new axis/diagonal
    });

    //------------------------------------------------------------------------------------------------------------------
    // Create a ground plane
    //------------------------------------------------------------------------------------------------------------------

    // new Mesh(viewer.scene, {
    //     geometry: new ReadableGeometry(viewer.scene, buildPlaneGeometry({
    //         xSize: 15000,
    //         zSize: 15000
    //     })),
    //     material: new PhongMaterial(viewer.scene, {
    //         diffuse: [0.3, 0.5, 0.1],
    //         // alpha: 0.0,
    //         alphaMode: "opaque"
    //     }),
    //     position: [1842761.9375, -5.53293939639616, -5174733.5],
    //     collidable: false
    // });

    //----------------------------------------------------------------------------------------------------------------------
    // Load nine CityGML models
    //----------------------------------------------------------------------------------------------------------------------

    const xktLoader = new XKTLoaderPlugin(viewer);

    const t0 = performance.now();

    document.getElementById("time").innerHTML = "Loading model 1 of 9";

    xktLoader.load({
        id: "lyon1",
        src: "../../assets/models/xkt/v7/Lyon/Lyon1.xkt",
        edges: true,
        saoEnabled: true,
        dtxEnabled: true
    }).on("loaded", () => {

        document.getElementById("time").innerHTML = "Loading model 2 of 9";

        xktLoader.load({
            id: "lyon2",
            src: "../../assets/models/xkt/v7/Lyon/Lyon2.xkt",
            edges: true,
            saoEnabled: true,
            dtxEnabled: true
        }).on("loaded", () => {

            document.getElementById("time").innerHTML = "Loading model 3 of 9";

            xktLoader.load({
                id: "lyon3",
                src: "../../assets/models/xkt/v7/Lyon/Lyon3.xkt",
                edges: true,
                saoEnabled: true,
                dtxEnabled: true
            }).on("loaded", () => {

                document.getElementById("time").innerHTML = "Loading model 4 of 9";

                xktLoader.load({
                    id: "lyon4",
                    src: "../../assets/models/xkt/v7/Lyon/Lyon4.xkt",
                    edges: true,
                    saoEnabled: true,
                    dtxEnabled: true
                }).on("loaded", () => {

                    document.getElementById("time").innerHTML = "Loading model 5 of 9";

                    xktLoader.load({
                        id: "Lyon5",
                        src: "../../assets/models/xkt/v7/Lyon/Lyon5.xkt",
                        edges: true,
                        saoEnabled: true,
                        dtxEnabled: true
                    }).on("loaded", () => {

                        document.getElementById("time").innerHTML = "Loading model 6 of 9";

                        xktLoader.load({
                            id: "Lyon6",
                            src: "../../assets/models/xkt/v7/Lyon/Lyon6.xkt",
                            edges: true,
                            saoEnabled: true,
                            dtxEnabled: true
                        }).on("loaded", () => {

                            document.getElementById("time").innerHTML = "Loading model 7 of 9";

                            xktLoader.load({
                                id: "Lyon7",
                                src: "../../assets/models/xkt/v7/Lyon/Lyon7.xkt",
                                edges: true,
                                saoEnabled: true,
                                dtxEnabled: true
                            }).on("loaded", () => {

                                document.getElementById("time").innerHTML = "Loading model 8 of 9";

                                xktLoader.load({
                                    id: "Lyon8",
                                    src: "../../assets/models/xkt/v7/Lyon/Lyon8.xkt",
                                    edges: true,
                                    saoEnabled: true,
                                    dtxEnabled: true
                                }).on("loaded", () => {

                                    document.getElementById("time").innerHTML = "Loading model 9 of 9";

                                    const lyon9 = xktLoader.load({
                                        id: "Lyon9",
                                        src: "../../assets/models/xkt/v7/Lyon/Lyon9.xkt",
                                        edges: true,
                                        saoEnabled: true
                                    });

                                    lyon9.on("loaded", () => {

                                        let numEntities = 0;

                                        for (let id in viewer.scene.models) {
                                            const sceneModel = viewer.scene.models[id];
                                            numEntities += sceneModel.numEntities;
                                        }

                                        const t1 = performance.now();

                                        document.getElementById("time").innerHTML = "Loaded 9 models in " + Math.floor((t1 - t0)) / 1000 + " seconds<br>Objects: " + numEntities;

                                    });
                                });
                            });
                        });
                    });
                });
            });
        });
    });

    window.camera = viewer.camera;

</script>
</html>
